#ifndef __CANYON_CORE_BUS
#define __CANYON_CORE_BUS

#include "../include/device_interface.hpp"

#include <vector>

namespace canyon{

class Bus{
    protected:
    struct DeviceInfo{
        DeviceInterface * device;
        bool callable;
    };
    std::vector<DeviceInfo> devices;

    public:

    bool verify_load(uint64_t device){
        return device < this->devices.size();
    }

    bool verify_call(uint64_t device){
        if(this->verify_load(device)){
            return this->devices[device].callable;
        }else return false;
    }

    public:

    void load(uint64_t device, Memory memory){
        if(this->verify_load(device)){
            this->devices[device].device -> load(memory);
            this->devices[device].callable = true;
        }
    }

    void call(uint64_t device, uint8_t code, uint64_t data){
        if(this->verify_call(device)){
            this->devices[device].device -> call(code, data);
        }else{
            // 异常中断，暂时不作处理
        }
    }

    public:

    void add_device(DeviceInterface * device, bool callable=false){
        this->devices.push_back({device, callable});
    }

    void unload(uint64_t device){
        if(this->verify_load(device)){
            this->devices[device].callable = false;
        }
    }

    DeviceInterface * get_device(uint64_t device){
        if(this->verify_load(device)){
            return this->devices[device].device;
        }else{
            // 异常中断，暂时不作处理
            return nullptr;
        }
    }

    size_t size(){
        return this->devices.size();
    }
};

}

#endif
